前一天我們學到 jq filter 可以經過判斷之後篩選出想要的資料,今天來看看 jq filter 如何讓結果轉換成我們想要的物件或陣列。
師傅:我們要來學習如何用 jq 建立新的 JSON 物件和陣列。準備好了嗎?
徒弟:是的,師傅!我已經迫不及待要學習新的技能了。
師傅:很好。首先,我們來看看如何建立一個新的 JSON 物件。試試這個命令:jq "{newObject: .}" todos.json
徒弟:哇!這是把整個 todos.json 的內容放到一個叫 newObject 的屬性裡了嗎?
師傅:沒錯。現在,讓我們試試建立一個新的陣列。執行這個:jq "[.[] | {id: .id, title: .title}]" todos.json
徒弟:這...這是建立了一個只有 id 和 title 屬性物件的新陣列?
師傅:正確。現在,讓我介紹一下 map 函數。map 會對陣列中的每個元素應用相同的轉換。試試這個:jq "map({id: .id, title: .title})" todos.json
徒弟:哦,這看起來跟剛才的結果一樣,但寫法更簡潔了!
師傅:沒錯。map 和直接使用 [] 的主要區別在於可讀性和複雜度。對於簡單的轉換,map 通常更清晰。但對於更複雜的操作,有時直接使用 [] 會更靈活。
徒弟:我明白了。那麼,我們應該在什麼時候選擇使用 map,什麼時候選擇使用 []?
師傅:好問題。一般來說,當你要對陣列中的每個元素進行相同的簡單轉換時,使用 map。如果你需要更複雜的邏輯或條件判斷,使用 [] 可能更合適。繼續練習,你會逐漸掌握使用的時機。
徒弟:謝謝師傅!我會努力練習的!
{} 建立新物件;使用 [] 建立新陣列先前學過使用 . 取得輸入的 JSON、 .{屬性} 取得 JSON 物件的屬性值、.[] 取得 JSON 陣列的元素。當我們想要轉換成需要的 JSON 格式時,可以透過 {} 或 [] 括住我們要取得的內容,來建立新的物件或陣列。
例如,原本的 TODO :
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
若只想看 id 和 title ,要組成 {"id": 1, "title": "delectus aut autem"} 這樣只有兩個屬性的物件,可以透過 {} 括住我們要取得的內容 id: .id , title: .title,也就是 {id: .id , title: .title} 建立新的物件。
值得一提的是 {id: .id , title: .title} 這個物件,因為他的新屬性 id 與原屬性 .id 名稱相同、新屬性 title 與原屬性 .title 名稱相同,因此有便捷的寫法:
{id, title}
jq ". | {id, title}" todo.json
jq "[.[] | {id, title}]" todos.json
上面兩個例子,互相對照之下,會更清楚{}和[]個別的使用時機。注意便捷的寫法只有名稱相同時才能使用,要改屬性名稱的話,當然要指定新屬性名稱囉!
map(filter表達式) ,這個 map 的作用,就是將自己前面接收到的的輸入值,執行 [.[] | filter表達式] 。例如對話中的 jq "[.[] | {id, title}]" todos.json 與 jq "map({id: .id, title: .title})" todos.json 有相同的結果,參考下圖使用 jqplay 執行兩者比較的結果。
![]() |
![]() |
|---|
今天學到了利用表達式{}和[],將輸入的資料轉換成自己想要的形式。也學到了 map 函式
的作用。我個人覺得 map 不是那麼直覺,因為我直覺想到的 map 也是 key:value 形式的那一種。不過一回生二回熟,之後若是有用到的時候,也能回頭查看這個 map 的定義啦! 感謝總是努力的自己~:)